package top.zlcode.ai.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import top.zlcode.ai.domain.AiApiCallRecord;
import top.zlcode.ai.domain.dto.DeepSeekDTO;
import top.zlcode.ai.domain.vo.DeepSeekVO;
import top.zlcode.ai.service.IAiApiCallRecordService;
import top.zlcode.ai.service.IChatService;
import top.zlcode.api.ai.domain.Message;
import top.zlcode.api.ai.domain.dto.ChatDTO;
import top.zlcode.api.ai.domain.vo.ChatVO;
import top.zlcode.common.core.constants.Constants;
import top.zlcode.common.core.domain.R;
import top.zlcode.common.core.enums.AiServiceType;
import top.zlcode.common.httpclient.service.HttpClientService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("ChatDeekSeekService")
public class ChatDeekSeekServiceImpl implements IChatService {

    @Autowired
    private HttpClientService httpClientService;

    @Autowired
    private IAiApiCallRecordService aiApiCallRecordService;

    /**
     * DeepSeek key
     */
    @Value("${ai.deepseek.api.key:sk-7f83692e7deb4050837cbf8a9d51df06}")
    private String apiKey;

    @Value("${ai.deepseek.api.chatUrl:https://api.deepseek.com/chat/completions}")
    private String chatUrl;

    @Value("${ai.deepseek.model.chat:deepseek-chat}")
    private String chatModel;

    @Value("${ai.deepseek.model.maxTokens:8000}")
    private Integer maxTokens;

    @Override
    public R<ChatVO> ask(ChatDTO chatDTO) {
        DeepSeekDTO deepseekDTO = buildDeepSeekDTO(chatDTO);
        return R.ok(callChatApi(deepseekDTO));
    }

    /**
     * 构造调用 deepseek 接口入参实体对象
     * @return DeepSeekDTO
     */
    private DeepSeekDTO buildDeepSeekDTO(ChatDTO chatDTO) {
        DeepSeekDTO deepseekDTO = new DeepSeekDTO();
        deepseekDTO.setMaxTokens(maxTokens);
        deepseekDTO.setModel(chatModel);
        BeanUtil.copyProperties(chatDTO, deepseekDTO);
        return deepseekDTO;
    }

    /**
     * 调用对话 api
     * @param deepSeekDTO 接口入参实体
     */
    private ChatVO callChatApi(DeepSeekDTO deepSeekDTO) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + apiKey);
        long startTime = System.currentTimeMillis();
        String body = httpClientService.postJson(chatUrl, deepSeekDTO, headers);
        long endTime = System.currentTimeMillis();
        DeepSeekVO deepSeekVO = JSON.parseObject(body, DeepSeekVO.class);

        // 写入执行记录
        toAiApiCallRecordEntityAndInsert(deepSeekVO, deepSeekDTO, endTime - startTime);

        return buildChatVO(deepSeekVO, deepSeekDTO);
    }

    private void toAiApiCallRecordEntityAndInsert(DeepSeekVO deepSeekVO, DeepSeekDTO deepSeekDTO, long responseTime) {
        AiApiCallRecord entity = new AiApiCallRecord();
        entity.setUrl(chatUrl);
        entity.setAiServiceType(AiServiceType.DEEP_SEEK.getType());
        entity.setApiResponseId(deepSeekVO.getId());
        entity.setModelName(deepSeekVO.getModel());
        entity.setPromptContent(JSON.toJSONString(deepSeekDTO.getMessages()));
        entity.setGeneratedContent(deepSeekVO.getChoices().get(0).getMessage().getContent());
        entity.setFinishReason(deepSeekVO.getChoices().get(0).getFinishReason());
        entity.setPromptTokens(deepSeekVO.getUsage().getPromptTokens());
        entity.setCompletionTokens(deepSeekVO.getUsage().getCompletionTokens());
        entity.setTotalTokens(deepSeekVO.getUsage().getTotalTokens());
        entity.setApiResponseTime(responseTime);
        aiApiCallRecordService.save(entity);
    }

    private ChatVO buildChatVO(DeepSeekVO deepSeekVO, DeepSeekDTO deepSeekDTO) {
        ChatVO respVO = new ChatVO();

        respVO.setCurrentContent(deepSeekVO.getChoices().get(0).getMessage().getContent());
        // 插入最新的
        List<Message> messageList = deepSeekDTO.getMessages();
        Message message = Message.builder()
                .role(deepSeekVO.getChoices().get(0).getMessage().getRole())
                .content(deepSeekVO.getChoices().get(0).getMessage().getContent())
                .build();
        messageList.add(message);
        respVO.setMessages(messageList);
        respVO.setModel(deepSeekVO.getModel());
        return respVO;
    }
}
